package com.rcloud.server.sealtalk.util;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.rcloud.server.sealtalk.constant.TokenConstant;
import com.rcloud.server.sealtalk.domain.Users;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.http.server.reactive.ServerHttpRequest;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 解如辉
 */
public class JwtUtils {
    /**
     * 从数据声明生成令牌
     *
     * @param users 登陆用户
     * @param secret    密钥
     * @return 令牌
     */
    public static String createToken(Users users, String secret) {
        //创造token
        Map<String, Object> claims = new HashMap<String, Object>();
        claims.put("userId", users.getId());
        claims.put("nickname", users.getNickname());
        String token = TokenConstant.PREFIX + Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512, secret).compact();
        return token;
    }

    /**
     * 从令牌中获取数据声明
     *
     * @param token  令牌
     * @param secret 密钥
     * @return 数据声明
     */
    public static Claims parseToken(String token, String secret) {
        return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
    }

    /**
     * 从令牌中获取LoginUser
     *
     * @param token  令牌
     * @param secret 密钥
     * @return 数据声明
     */
    public static Users getLoginUserFromToken(String token, String secret) {
        Claims claims = parseToken(token, secret);
        return BeanUtil.fillBeanWithMap(claims, new Users(), false);
    }

    /**
     * 从令牌中获取userId
     *
     * @param token  令牌
     * @param secret 密钥
     * @return 数据声明
     */
    public static Long getUserIdToken(String token, String secret) {
        Claims claims = parseToken(token, secret);
        return Long.parseLong(claims.get("userId").toString());
    }

    /**
     * 获取请求token
     */
    public static String getToken(HttpServletRequest request) {
        String token = request.getHeader(TokenConstant.AUTHENTICATION);
        if (StrUtil.isNotEmpty(token) && token.startsWith(TokenConstant.PREFIX)) {
            // 如果前端设置了令牌前缀，则裁剪掉前缀
            token = token.replaceFirst(TokenConstant.PREFIX, StrUtil.EMPTY);
        }
        return token;
    }

}
